#include <string.h>
#include "redintobject.h"
#include "redboolobject.h"
#include "rednullobject.h"
#include "redfloatobject.h"
#include "redstringobject.h"
#include "redexceptionobject.h"

static RedObject *bool_repr(RedObject *self)
{
	if (self == Red_True)
		return RedString_FromCString("true");
	else
		return RedString_FromCString("false");
}

RedTypeObject RedType_Bool =
{
	RedType_INIT("bool", RedBoolObject, RedType_Object)

	.tp_str		= bool_repr,
	.tp_repr	= bool_repr,
};

RedBoolObject RedBool_True =
{
	RedObject_HEAD_INIT(RedType_Bool)
};

RedBoolObject RedBool_False =
{
	RedObject_HEAD_INIT(RedType_Bool)
};

char RedBool_IsTrue(RedObject *self)
{
	/* `null` is false */
	if (self == Red_Null)
		return 0;

	/* `true` is true */
	if (self == Red_True)
		return 1;

	/* `false` is false */
	if (self == Red_False)
		return 0;

	/* `0` is false */
	if (RedInt_Exact(self) && (RedInt_Value(self) == 0))
		return 0;

	/* `0.0` is false */
	if (RedFloat_Exact(self) && (RedFloat_Value(self) == 0.0f))
		return 0;

	/* `''` (empty string) is false */
	if (RedString_Exact(self) && (RedString_Length(self) == 0))
		return 0;

	/* objects that not equals to `false` are true */
	RedObject *result = RedObject_Neq(self, Red_False);

	/* not comparable with false, absolutely true */
	if (!result)
	{
		RedException_Clear();
		return 1;
	}

	if (RedBool_IsTrue(result))
	{
		Red_UNREF(result);
		return 1;
	}

	Red_UNREF(result);
	return 0;
}
